package com.cencat.user.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cencat.common.response.ApiResponse;
import com.cencat.common.response.PageResponse;
import com.cencat.user.dto.PermissionCreateDTO;
import com.cencat.user.dto.PermissionQueryDTO;
import com.cencat.user.dto.PermissionUpdateDTO;
import com.cencat.user.service.PermissionService;
import com.cencat.user.vo.PermissionListVO;
import com.cencat.user.vo.PermissionVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;

/**
 * 权限管理控制器
 * @author cencat
 * @since 2024-01-01
 */
@RestController
@RequestMapping("/api/permission")
@Tag(name = "权限管理", description = "权限管理相关接口")
@Slf4j
public class PermissionController {

    @Autowired
    private PermissionService permissionService;

    /**
     * 创建权限
     * @param dto 权限创建DTO
     * @return 权限ID
     */
    @PostMapping("/create")
    @Operation(summary = "创建权限", description = "创建新的权限")
    public ApiResponse<Long> createPermission(@Valid @RequestBody PermissionCreateDTO dto) {
        try {
            Long permissionId = permissionService.createPermission(dto);
            return ApiResponse.success(permissionId);
        } catch (Exception e) {
            log.error("创建权限失败: {}", e.getMessage(), e);
            return ApiResponse.error("创建权限失败: " + e.getMessage());
        }
    }

    /**
     * 更新权限
     * @param dto 权限更新DTO
     * @return 是否成功
     */
    @PutMapping("/update")
    @Operation(summary = "更新权限", description = "更新权限信息")
    public ApiResponse<Boolean> updatePermission(@Valid @RequestBody PermissionUpdateDTO dto) {
        try {
            Boolean result = permissionService.updatePermission(dto);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("更新权限失败: {}", e.getMessage(), e);
            return ApiResponse.error("更新权限失败: " + e.getMessage());
        }
    }

    /**
     * 删除权限
     * @param id 权限ID
     * @param tenantId 租户ID
     * @return 是否成功
     */
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除权限", description = "根据ID删除权限")
    public ApiResponse<Boolean> deletePermission(
            @Parameter(description = "权限ID", required = true) @PathVariable @Min(1) Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = permissionService.deletePermission(id, tenantId);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("删除权限失败: permissionId={}, error={}", id, e.getMessage(), e);
            return ApiResponse.error("删除权限失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除权限
     * @param ids 权限ID列表
     * @param tenantId 租户ID
     * @return 是否成功
     */
    @DeleteMapping("/batch-delete")
    @Operation(summary = "批量删除权限", description = "批量删除权限")
    public ApiResponse<Boolean> batchDeletePermissions(
            @Parameter(description = "权限ID列表", required = true) @RequestBody @NotEmpty List<Long> ids,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = permissionService.batchDeletePermissions(ids, tenantId);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("批量删除权限失败: permissionIds={}, error={}", ids, e.getMessage(), e);
            return ApiResponse.error("批量删除权限失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID获取权限详情
     * @param id 权限ID
     * @param tenantId 租户ID
     * @return 权限详情
     */
    @GetMapping("/get/{id}")
    @Operation(summary = "获取权限详情", description = "根据ID获取权限详情")
    public ApiResponse<PermissionVO> getPermissionById(
            @Parameter(description = "权限ID", required = true) @PathVariable @Min(1) Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            PermissionVO permission = permissionService.getPermissionById(id, tenantId);
            return ApiResponse.success(permission);
        } catch (Exception e) {
            log.error("获取权限详情失败: permissionId={}, error={}", id, e.getMessage(), e);
            return ApiResponse.error("获取权限详情失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询权限列表
     * @param queryDTO 查询条件
     * @return 权限分页列表
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询权限", description = "分页查询权限列表")
    public ApiResponse<PageResponse<PermissionListVO>> getPermissionPage(@Valid @RequestBody PermissionQueryDTO queryDTO) {
        try {
            PageResponse<PermissionListVO> permissionPage = permissionService.getPermissionPage(queryDTO);
            return ApiResponse.success(permissionPage);
        } catch (Exception e) {
            log.error("分页查询权限失败: {}", e.getMessage(), e);
            return ApiResponse.error("分页查询权限失败: " + e.getMessage());
        }
    }

    /**
     * 查询权限列表
     * @param queryDTO 查询条件
     * @return 权限列表
     */
    @PostMapping("/list")
    @Operation(summary = "查询权限列表", description = "查询权限列表")
    public ApiResponse<List<PermissionListVO>> getPermissionList(@Valid @RequestBody PermissionQueryDTO queryDTO) {
        try {
            List<PermissionListVO> list = permissionService.getPermissionList(queryDTO);
            return ApiResponse.success(list);
        } catch (Exception e) {
            log.error("查询权限列表失败: {}", e.getMessage(), e);
            return ApiResponse.error("查询权限列表失败: " + e.getMessage());
        }
    }

    /**
     * 查询权限树形结构
     * @param tenantId 租户ID
     * @return 权限树形列表
     */
    @GetMapping("/tree")
    @Operation(summary = "查询权限树", description = "查询权限树形结构")
    public ApiResponse<List<PermissionVO>> getPermissionTree(
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            List<PermissionVO> tree = permissionService.getPermissionTree(tenantId);
            return ApiResponse.success(tree);
        } catch (Exception e) {
            log.error("查询权限树失败: tenantId={}, error={}", tenantId, e.getMessage(), e);
            return ApiResponse.error("查询权限树失败: " + e.getMessage());
        }
    }

    /**
     * 启用权限
     * @param id 权限ID
     * @param tenantId 租户ID
     * @return 是否成功
     */
    @PutMapping("/enable/{id}")
    @Operation(summary = "启用权限", description = "启用权限")
    public ApiResponse<Boolean> enablePermission(
            @Parameter(description = "权限ID", required = true) @PathVariable @Min(1) Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = permissionService.enablePermission(id, tenantId);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("启用权限失败: permissionId={}, error={}", id, e.getMessage(), e);
            return ApiResponse.error("启用权限失败: " + e.getMessage());
        }
    }

    /**
     * 禁用权限
     * @param id 权限ID
     * @param tenantId 租户ID
     * @return 是否成功
     */
    @PutMapping("/disable/{id}")
    @Operation(summary = "禁用权限", description = "禁用权限")
    public ApiResponse<Boolean> disablePermission(
            @Parameter(description = "权限ID", required = true) @PathVariable @Min(1) Long id,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Boolean result = permissionService.disablePermission(id, tenantId);
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("禁用权限失败: permissionId={}, error={}", id, e.getMessage(), e);
            return ApiResponse.error("禁用权限失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新权限状态
     * @param request 批量更新请求
     * @return 是否成功
     */
    @PutMapping("/batch-update-status")
    @Operation(summary = "批量更新权限状态", description = "批量更新权限状态")
    public ApiResponse<Boolean> batchUpdatePermissionStatus(@Valid @RequestBody BatchUpdateStatusRequest request) {
        try {
            Boolean result = permissionService.batchUpdatePermissionStatus(request.getIds(), request.getStatus(), request.getTenantId());
            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("批量更新权限状态失败: {}", e.getMessage(), e);
            return ApiResponse.error("批量更新权限状态失败: " + e.getMessage());
        }
    }

    /**
     * 检查权限编码是否存在
     * @param permissionCode 权限编码
     * @param excludeId 排除的权限ID
     * @param tenantId 租户ID
     * @return 是否存在
     */
    @GetMapping("/check-code")
    @Operation(summary = "检查权限编码", description = "检查权限编码是否存在")
    public ApiResponse<Boolean> checkPermissionCodeExists(
            @Parameter(description = "权限编码", required = true) @RequestParam String permissionCode,
            @Parameter(description = "排除的权限ID") @RequestParam(required = false) Long excludeId,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Boolean exists = permissionService.checkPermissionCodeExists(permissionCode, excludeId, tenantId);
            return ApiResponse.success(exists);
        } catch (Exception e) {
            log.error("检查权限编码失败: permissionCode={}, error={}", permissionCode, e.getMessage(), e);
            return ApiResponse.error("检查权限编码失败: " + e.getMessage());
        }
    }

    /**
     * 检查权限名称是否存在
     * @param permissionName 权限名称
     * @param excludeId 排除的权限ID
     * @param tenantId 租户ID
     * @return 是否存在
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查权限名称", description = "检查权限名称是否存在")
    public ApiResponse<Boolean> checkPermissionNameExists(
            @Parameter(description = "权限名称", required = true) @RequestParam String permissionName,
            @Parameter(description = "排除的权限ID") @RequestParam(required = false) Long excludeId,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Boolean exists = permissionService.checkPermissionNameExists(permissionName, excludeId, tenantId);
            return ApiResponse.success(exists);
        } catch (Exception e) {
            log.error("检查权限名称失败: permissionName={}, error={}", permissionName, e.getMessage(), e);
            return ApiResponse.error("检查权限名称失败: " + e.getMessage());
        }
    }

    /**
     * 根据父权限ID查询子权限
     * @param parentId 父权限ID
     * @param tenantId 租户ID
     * @return 子权限列表
     */
    @GetMapping("/children/{parentId}")
    @Operation(summary = "查询子权限", description = "根据父权限ID查询子权限")
    public ApiResponse<List<PermissionVO>> getChildrenByParentId(
            @Parameter(description = "父权限ID", required = true) @PathVariable @Min(0) Long parentId,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            List<PermissionVO> children = permissionService.getChildrenByParentId(parentId, tenantId);
            return ApiResponse.success(children);
        } catch (Exception e) {
            log.error("查询子权限失败: parentId={}, error={}", parentId, e.getMessage(), e);
            return ApiResponse.error("查询子权限失败: " + e.getMessage());
        }
    }

    /**
     * 根据权限类型查询权限
     * @param permissionType 权限类型
     * @param tenantId 租户ID
     * @return 权限列表
     */
    @GetMapping("/type/{permissionType}")
    @Operation(summary = "按类型查询权限", description = "根据权限类型查询权限")
    public ApiResponse<List<PermissionVO>> getPermissionsByType(
            @Parameter(description = "权限类型（1-菜单，2-按钮，3-接口）", required = true) @PathVariable @Min(1) Integer permissionType,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            List<PermissionVO> permissions = permissionService.getPermissionsByType(permissionType, tenantId);
            return ApiResponse.success(permissions);
        } catch (Exception e) {
            log.error("按类型查询权限失败: permissionType={}, error={}", permissionType, e.getMessage(), e);
            return ApiResponse.error("按类型查询权限失败: " + e.getMessage());
        }
    }

    /**
     * 根据用户ID查询用户权限
     * @param userId 用户ID
     * @param tenantId 租户ID
     * @return 权限列表
     */
    @GetMapping("/user/{userId}")
    @Operation(summary = "查询用户权限", description = "根据用户ID查询用户权限")
    public ApiResponse<List<PermissionVO>> getPermissionsByUserId(
            @Parameter(description = "用户ID", required = true) @PathVariable @Min(1) Long userId,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            List<PermissionVO> permissions = permissionService.getPermissionsByUserId(userId, tenantId);
            return ApiResponse.success(permissions);
        } catch (Exception e) {
            log.error("查询用户权限失败: userId={}, error={}", userId, e.getMessage(), e);
            return ApiResponse.error("查询用户权限失败: " + e.getMessage());
        }
    }

    /**
     * 根据角色ID查询角色权限
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 权限列表
     */
    @GetMapping("/role/{roleId}")
    @Operation(summary = "查询角色权限", description = "根据角色ID查询角色权限")
    public ApiResponse<List<PermissionVO>> getPermissionsByRoleId(
            @Parameter(description = "角色ID", required = true) @PathVariable @Min(1) Long roleId,
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            List<PermissionVO> permissions = permissionService.getPermissionsByRoleId(roleId, tenantId);
            return ApiResponse.success(permissions);
        } catch (Exception e) {
            log.error("查询角色权限失败: roleId={}, error={}", roleId, e.getMessage(), e);
            return ApiResponse.error("查询角色权限失败: " + e.getMessage());
        }
    }

    /**
     * 获取权限统计信息
     * @param tenantId 租户ID
     * @return 统计信息
     */
    @GetMapping("/count")
    @Operation(summary = "权限统计", description = "获取权限统计信息")
    public ApiResponse<Long> getPermissionCount(
            @Parameter(description = "租户ID", required = true) @RequestParam @NotNull Long tenantId) {
        try {
            Long count = permissionService.getPermissionCount(tenantId);
            return ApiResponse.success(count);
        } catch (Exception e) {
            log.error("获取权限统计失败: tenantId={}, error={}", tenantId, e.getMessage(), e);
            return ApiResponse.error("获取权限统计失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新状态请求类
     */
    public static class BatchUpdateStatusRequest {
        @NotEmpty(message = "权限ID列表不能为空")
        private List<Long> ids;
        
        @NotNull(message = "状态不能为空")
        private Integer status;
        
        @NotNull(message = "租户ID不能为空")
        private Long tenantId;

        // Getters and Setters
        public List<Long> getIds() {
            return ids;
        }

        public void setIds(List<Long> ids) {
            this.ids = ids;
        }

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }

        public Long getTenantId() {
            return tenantId;
        }

        public void setTenantId(Long tenantId) {
            this.tenantId = tenantId;
        }
    }

}